package method

import (
	"errors"
	"fmt"
	"log"
	"time"

	"github.com/golang-jwt/jwt/v4"
)

func CreateToken(id int64) (string, error) {
	claims := jwt.MapClaims{
		"id":  id,
		"exp": time.Now().Add(time.Hour * 24 * 365).Unix(),
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 使用密钥签名Token
	tokenString, err := token.SignedString([]byte(Config.Server.TokenKey))
	if err != nil {
		return "", err
	}

	return tokenString, nil
}
func VerifyToken(tokenString string) (bool, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// 验证Token的Signing Method
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("意外的签名方法: %v", token.Header["alg"])
		}

		return []byte(Config.Server.TokenKey), nil
	})

	if err != nil {
		return false, fmt.Errorf("jwt: %w", err) // 使用fmt.Errorf来包装原始错误
	}

	if _, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return true, nil
	}
	return false, errors.New("Token无效")
}

func ParseClaims(token *jwt.Token) (jwt.MapClaims, error) {
	if token == nil {
		log.Printf("ParseClaims: token is nil")
		return nil, errors.New("jwt: token cannot be nil")
	}

	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return claims, nil
	}

	log.Printf("ParseClaims: token invalid, Type: %T, Valid: %v", token.Claims, token.Valid)
	return nil, errors.New("token无效")
}

func GetTokenId(tokenString string) (int64, error) {
	parsedToken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// 这里和 VerifyToken 中的验证逻辑相同
		// ...
		return []byte(Config.Server.TokenKey), nil
	})

	if err != nil {
		return 0, err
	}
	tokenData, err := ParseClaims(parsedToken)
	if err != nil {
		return 0, err
	}

	idFloat64, ok := tokenData["id"].(float64)
	if !ok {
		return 0, fmt.Errorf("invalid ID type, expected float64")
	}
	idInt64 := int64(idFloat64)
	return idInt64, nil
}
